package org.lemon.transport.mqtt.server.adaptors;

import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.handler.codec.mqtt.MqttMessage;
import io.netty.handler.codec.mqtt.MqttPublishMessage;
import org.lemon.transport.context.adaptor.AdaptorException;
import org.server.transport.gen.TransportProto;
import org.server.transport.gen.TransportProto.*;
import org.lemon.transport.mqtt.server.session.MqttDeviceAwareSessionContext;

import java.util.Optional;

public interface MqttTransportAdaptor {

    ByteBufAllocator ALLOCATOR = new UnpooledByteBufAllocator(false);

    /**
     * 遥测数据转化
     *
     * @param ctx
     * @param inbound
     * @return
     * @throws AdaptorException
     */
    PostTelemetryMsg convertToPostTelemetry(MqttDeviceAwareSessionContext ctx, MqttPublishMessage inbound) throws AdaptorException;

    /**
     * 属性数据
     *
     * @param ctx
     * @param inbound
     * @return
     * @throws AdaptorException
     */
    PostAttributeMsg convertToPostAttributes(MqttDeviceAwareSessionContext ctx, MqttPublishMessage inbound) throws AdaptorException;

    ProvisionDeviceRequestMsg convertToProvisionRequestMsg(MqttDeviceAwareSessionContext ctx, MqttPublishMessage inbound) throws AdaptorException;

    Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext deviceSessionCtx, ProvisionDeviceResponseMsg provisionResponseMsg);

    Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext deviceSessionCtx, ProvisionDeviceResponseMsg provisionResponseMsg, String topicName);

    /**
     * 属性更新消息发布通知
     *
     * @param deviceSessionCtx
     * @param notificationMsg
     * @param topicName
     * @return
     * @throws AdaptorException
     */
    Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext deviceSessionCtx, AttributeUpdateNotificationMsg notificationMsg, String topicName) throws AdaptorException;

    /**
     * 获取设备属性的响应消息
     *
     * @param deviceSessionCtx
     * @param attributesResponse
     * @param topicName
     * @return
     * @throws AdaptorException
     */
    Optional<MqttMessage> convertToPublish(MqttDeviceAwareSessionContext deviceSessionCtx, TransportProto.GetAttributeResponseMsg attributesResponse, String topicName) throws AdaptorException;

}
